﻿// Copyright (c) Inossem. All rights reserved.
// Licensed under the LGPL-3.0 license. See LICENSE file in the project root for full license information.
using DWF.Studio.ScriptEngine.IPC.Msg;
using DWF.Studio.Share.Log;
using NamedPipeWrapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DWF.Studio.ScriptEngine.IPC.NamedPipe
{
    /// <summary>
    /// 命名管道服务
    /// </summary>
    public class NamedPipeService
    {
        /// <summary>
        /// 已连接
        /// </summary>
        public Action<NamedPipeConnectionExAsync<UpwardMsg, DownwardMsg>> Connected
        {
            set;
            get;
        }

        /// <summary>
        /// 已断开连接
        /// </summary>
        public Action<NamedPipeConnectionExAsync<UpwardMsg, DownwardMsg>> Disconnected
        {
            set;
            get;
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        public Action<UpwardMsg> ReceiveMessage
        {
            set;
            get;
        }

        /// <summary>
        /// 未处理错误
        /// </summary>
        public Action<Exception> UnhandleError
        {
            set;
            get;
        }

        private string _pipeName = "RemoteEnginePipe";

        /// <summary>
        /// 管道名
        /// </summary>
        public string PipeName
        {
            get
            {
                return _pipeName;
            }
        }

        /// <summary>
        /// 命名管道服务器
        /// </summary>
        private NamedPipeServerExAsync<UpwardMsg, DownwardMsg> _pipeServer = null;

        /// <summary>
        /// 
        /// </summary>
        public NamedPipeService()
        {
            _pipeServer = new NamedPipeServerExAsync<UpwardMsg, DownwardMsg>(_pipeName);
            _pipeServer.ClientConnected += (connection) => { Connected?.Invoke(connection); };
            _pipeServer.ClientDisconnected += (connection) => { Disconnected?.Invoke(connection); };
            _pipeServer.ClientMessage += (connection, message) => { ReceiveMessage?.Invoke(message); };
            _pipeServer.Error += onError;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pipeName"></param>
        public NamedPipeService(string pipeName)
        {
            _pipeName = pipeName;
            _pipeServer = new NamedPipeServerExAsync<UpwardMsg, DownwardMsg>(pipeName);
            _pipeServer.ClientConnected += (connection) => { Connected?.Invoke(connection); };
            _pipeServer.ClientDisconnected += (connection) => { Disconnected?.Invoke(connection); };
            _pipeServer.ClientMessage += (connection, message) => { ReceiveMessage?.Invoke(message); };
            _pipeServer.Error += onError;
        }

        /// <summary>
        /// 开始
        /// </summary>
        public void Start()
        {
            _pipeServer.Start();
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            _pipeServer.Stop();
        }

        private void onError(Exception exception)
        {
            LogHelper.Error(exception);
            UnhandleError?.Invoke(exception);
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message"></param>
        public void Send(DownwardMsg message)
        {
            _pipeServer.PushMessage(message);
        }

        /// <summary>
        /// 异步发送消息
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendAsync(DownwardMsg message)
        {
            await _pipeServer.PushMessageAsync(message);
        }
    }
}
